/*
 * @(#)SOAPContextParser.java
 * Date 2014-01-17
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.ws;

import javax.enterprise.context.ApplicationScoped;

import javax.xml.ws.WebServiceContext;

import javax.xml.ws.handler.MessageContext;

import org.apache.commons.lang3.ClassUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import us.hornerscorners.lamppost.config.IServiceConfig;

import us.hornerscorners.lamppost.model.audit.AuditContext;
import us.hornerscorners.lamppost.model.audit.CodedValueType;


/**
 * Class description
 *
 *
 * @version        v1.0, 2014-01-17
 * @author         Jim Horner
 */
@ApplicationScoped
public class SOAPContextParser {

    /** Field description */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * Constructs ...
     *
     */
    public SOAPContextParser() {
        super();
    }

    /**
     * Method description
     *
     *
     * @param context
     *
     * @return
     */
    public AddressContext parseAddressContext(WebServiceContext context) {

        return parseContext(context, SOAPAddressHandler.ADDRESS_CONTEXT,
                            AddressContext.class);
    }

    /**
     * Method description
     *
     *
     * @param context
     * @param eventType
     * @param serviceConfig
     *
     * @return
     */
    public AuditContext parseAuditContext(WebServiceContext context,
            CodedValueType eventType, IServiceConfig serviceConfig) {

        AddressContext addressContext = parseAddressContext(context);
        TransactionContext transactionContext = parseTransactionContext(context);

        return new AuditContext(eventType, serviceConfig, transactionContext,
                                addressContext);
    }

    /**
     * Method description
     *
     *
     * @param context
     * @param key
     * @param resultType
     * @param <T>
     *
     * @return
     */
    @SuppressWarnings(value = "unchecked")
    private <T> T parseContext(WebServiceContext context, String key,
                               Class<T> resultType) {

        T result = null;

        MessageContext msgctx = context.getMessageContext();

        Object obj = msgctx.get(key);

        if (resultType.isInstance(obj)) {

            result = (T) obj;
        } else {

            String clz = "NO VALUE";

            if (obj != null) {
                clz = ClassUtils.getShortClassName(obj.getClass());
            }

            logger.warn("Not of proper type, expecting {} found {}",
                        ClassUtils.getShortClassName(resultType), clz);
        }

        return result;

    }

    /**
     * Method description
     *
     *
     * @param context
     *
     * @return
     */
    public TransactionContext parseTransactionContext(WebServiceContext context) {

        return parseContext(context, SOAPTransactionHandler.TRANSACTION_CONTEXT,
                            TransactionContext.class);
    }
}
